package wymiana.mbeans.file;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.SessionScoped;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.primefaces.model.UploadedFile;

import wymiana.config.ApplicationProperties;
import wymiana.domain.DGroup;
import wymiana.domain.Department;
import wymiana.domain.UploadedFiles;
import wymiana.domain.User;
import wymiana.enumeration.FileType;
import wymiana.mbeans.UserBean;
import wymiana.service.GroupService;
import wymiana.service.PhotoService;
import wymiana.service.SchoolService;
import wymiana.service.UploadedFileService;
import wymiana.service.UserService;

@ManagedBean(name = "fileMBean")
// @RequestScoped
@SessionScoped
public class FileMBean implements Serializable {

	/** serialization uid */
	private static final long serialVersionUID = 915050337580336422L;
	private static final Logger logger = Logger.getLogger(FileMBean.class);
	/** lista szkol */
	private List<UploadedFiles> files = null;

	private List<UploadedFiles> filteredFiles = null;

	/** aktualnie wybrana uczelnia */
	private UploadedFiles actualFile = null;

	private UploadedFile uploadedFile = null;

	@ManagedProperty("#{userService}")
	private UserService userService;

	@ManagedProperty("#{schoolService}")
	private SchoolService schoolService;

	@ManagedProperty("#{photoService}")
	private PhotoService photoService;

	@ManagedProperty("#{groupService}")
	private GroupService groupService;

	@ManagedProperty("#{userMBean}")
	private UserBean userMBean;

	@ManagedProperty("#{uploadedFileService}")
	private UploadedFileService uploadedFileService;

	private String choosenId = null;

	public FileMBean() {
		// TODO inicjalizacja MBeana

	}

	public String goToFiles() {
		return "file";
	}

	public String goToPersonalFiles() {
		return "personalFiles";
	}

	public String editFile() {
		ExternalContext externalContext = FacesContext.getCurrentInstance()
				.getExternalContext();

		String fileId = (String) externalContext.getRequestParameterMap().get(
				"fileId");
		actualFile = uploadedFileService.getUploadedFile(Integer
				.parseInt(fileId));

		choosenId = actualFile.getDgroup().getIdGroup().toString();
		return "editFile";
	}

	public String addFile() {
		actualFile = new UploadedFiles();

		return "addFile";
	}

	public String getChoosenGroup() {
		try {
			DGroup g = groupService.getGroup(Integer.parseInt(choosenId));
			return g.getName();
		} catch (Exception e) {

		}
		return "";
	}

	public String removeFile() {
		ExternalContext externalContext = FacesContext.getCurrentInstance()
				.getExternalContext();

		String fileId = (String) externalContext.getRequestParameterMap().get(
				"fileId");
		// School s = schoolService.getSchool(Integer.parseInt(schoolId));
		setFiles(null);

		uploadedFileService.deleteFileByID(Integer.parseInt(fileId));
		return "";
	}

	public String showFile() {
		ExternalContext externalContext = FacesContext.getCurrentInstance()
				.getExternalContext();

		String fileId = (String) externalContext.getRequestParameterMap().get(
				"fileId");
		actualFile = uploadedFileService.getUploadedFile(Integer
				.parseInt(fileId));

		return "showFile";
	}

	public String saveFile() {

		if (actualFile.getIdFile() == null) {
			actualFile.setCreationDate(new Date());
			DGroup g = groupService.getGroup(Integer.parseInt(choosenId));
			actualFile.setDgroup(g);
			if (uploadedFile == null) {
				FacesMessage message = new FacesMessage(
						FacesMessage.SEVERITY_ERROR, "Błąd: ",
						"Nie wybrano pliku.");

				FacesContext.getCurrentInstance().addMessage(null, message);
				return "";
			}
			long size = uploadedFile.getSize();
			double sMb = (double) size / (1024 * 1024);
			// type: image/jpg, application/pdf, text/plain,
			// application/octet-stream(zip/rar), application/msword,
			// application/vnd.ms-excel

			String type = uploadedFile.getContentType();
			FileType fileType = null;
			if (type.indexOf("jpg") >= 0 || type.indexOf("png") >= 0
					|| type.indexOf("gif") >= 0 || type.indexOf("image") >= 0) {
				fileType = FileType.PHOTO;
			} else if (type.indexOf("pdf") >= 0
					|| type.indexOf("text/plain") >= 0
					|| type.indexOf("msword") >= 0
					|| type.indexOf("vnd.ms-excel") >= 0) {
				fileType = FileType.PDF_DOC;
			} else if (type.indexOf("octet-stream") >= 0) {
				fileType = FileType.Archiwum;
			} else {
				FacesMessage message = new FacesMessage(
						FacesMessage.SEVERITY_INFO, "Błąd: ",
						"Nieobsługiwany typ pliku");
				FacesContext.getCurrentInstance().addMessage(null, message);
				return "";
			}
			User u = userMBean.getLoggedUser();
			actualFile.setCreateUser(u);
			actualFile.setFilename(uploadedFile.getFileName());
			SimpleDateFormat format = new SimpleDateFormat("yyyy_MM_dd");
			String dFolder = format.format(actualFile.getCreationDate());
			format = new SimpleDateFormat("yyyy_MM_dd_hh_mm_ss");
			String prefix = format.format(actualFile.getCreationDate());
			String filepath = ApplicationProperties.FILE_PATH + "grupa\\"
					+ dFolder + "\\" + prefix + uploadedFile.getFileName();

			actualFile.setFilePath(filepath);
			actualFile.setFileType(fileType);
			actualFile.setSize((sMb + "").toString().substring(0, 5) + " MB");

			try {
				writeToFile(uploadedFile.getInputstream(), new File(
						ApplicationProperties.FILE_PATH + "grupa\\" + dFolder
								+ "\\"), prefix + uploadedFile.getFileName());
			} catch (IOException e) {
				logger.error("saveFile", e);
			}
			uploadedFileService.create(actualFile);
		}

		this.uploadedFileService.updateUploadedFile(actualFile);

		FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO,
				"Sukces: ", "Zapisano zmiany");

		FacesContext.getCurrentInstance().addMessage(null, message);
		boolean contains = false;

		for (UploadedFiles s : getFiles()) {
			if (s.getIdFile().equals(actualFile.getIdFile())) {
				contains = true;
				getFiles().remove(s);
				getFiles().add(s);
			}
		}

		if (!contains) {
			getFiles().add(actualFile);
			actualFile = null;
		}
		choosenId = null;

		return "personalFiles";
	}

	public void writeToFile(InputStream is, File file, String filename) {
		try {
			file.mkdirs();
			FileOutputStream out = new FileOutputStream(new File(file.getPath()
					+ "\\" + filename));
			int c;
			while ((c = is.read()) != -1) {
				out.write(c);
			}
			is.close();
			out.close();
		} catch (IOException e) {
			System.err.println("Error Writing/Reading Streams.");
		}
	}

	public String saveEditedFile() {
		saveFile();
		return "";
	}

	public void downloadFile() {
		ExternalContext externalContext = FacesContext.getCurrentInstance()
				.getExternalContext();

		String fileId = (String) externalContext.getRequestParameterMap().get(
				"fileId");
		UploadedFiles f = uploadedFileService.getUploadedFile(Integer
				.parseInt(fileId));
		String path = f.getFilePath();
		File file = new File(path);
		HttpServletResponse response = (HttpServletResponse) FacesContext
				.getCurrentInstance().getExternalContext().getResponse();

		response.setHeader("Content-Disposition",
				"attachment;filename=" + f.getFilename());
		response.setContentLength((int) file.length());
		ServletOutputStream out = null;
		try {
			FileInputStream input = new FileInputStream(file);
			byte[] buffer = new byte[1024];
			out = response.getOutputStream();
			int i = 0;
			while ((i = input.read(buffer)) != -1) {
				out.write(buffer);
				out.flush();
			}
			FacesContext.getCurrentInstance().getResponseComplete();
		} catch (IOException err) {
			err.printStackTrace();
		} finally {
			try {
				if (out != null) {
					out.close();
				}
			} catch (IOException err) {
				err.printStackTrace();
			}
		}

	}

	public List<UploadedFiles> getPersonalFiles() {
		User u = userMBean.getLoggedUser();
		u = userService.getUserByUsername(u.getUsername());
		List<UploadedFiles> personalFiles = uploadedFileService
				.getPersonalFiles(u);

		return personalFiles;
	}

	/**
	 * @return the schools
	 */
	public List<UploadedFiles> getFiles() {
		if (files == null) {
			files = uploadedFileService.getAllUploadedFiles();
		}
		return files;
	}

	/**
	 * @return the schoolService
	 */
	public SchoolService getSchoolService() {
		return schoolService;
	}

	/**
	 * @param schools
	 *            the schools to set
	 */
	public void setFiles(List<UploadedFiles> files) {
		this.files = files;
	}

	/**
	 * @param schoolService
	 *            the schoolService to set
	 */
	public void setSchoolService(SchoolService schoolService) {
		this.schoolService = schoolService;
	}

	/**
	 * @return the actualSchool
	 */
	public UploadedFiles getActualFile() {
		return actualFile;
	}

	/**
	 * @param actualSchool
	 *            the actualSchool to set
	 */
	public void setActualFile(UploadedFiles actualFile) {
		this.actualFile = actualFile;
	}

	/**
	 * @return the photoService
	 */
	public PhotoService getPhotoService() {
		return photoService;
	}

	/**
	 * @param photoService
	 *            the photoService to set
	 */
	public void setPhotoService(PhotoService photoService) {
		this.photoService = photoService;
	}

	public UploadedFile getUploadedFile() {
		return uploadedFile;
	}

	public void setUploadedFile(UploadedFile uploadedFile) {
		this.uploadedFile = uploadedFile;
	}

	public GroupService getGroupService() {
		return groupService;
	}

	public void setGroupService(GroupService groupService) {
		this.groupService = groupService;
	}

	public UploadedFileService getUploadedFileService() {
		return uploadedFileService;
	}

	public void setUploadedFileService(UploadedFileService uploadedFileService) {
		this.uploadedFileService = uploadedFileService;
	}

	public UserBean getUserMBean() {
		return userMBean;
	}

	public void setUserMBean(UserBean userMBean) {
		this.userMBean = userMBean;
	}

	public String getChoosenId() {
		return choosenId;
	}

	public void setChoosenId(String choosenId) {
		this.choosenId = choosenId;
	}

	public UserService getUserService() {
		return userService;
	}

	public void setUserService(UserService userService) {
		this.userService = userService;
	}

	/**
	 * @return the filteredFiles
	 */
	public List<UploadedFiles> getFilteredFiles() {
		return filteredFiles;
	}

	/**
	 * @param filteredFiles
	 *            the filteredFiles to set
	 */
	public void setFilteredFiles(List<UploadedFiles> filteredFiles) {
		this.filteredFiles = filteredFiles;
	}

}
